#include "Frame.h"
#include <stdlib.h>
#include "FileReader.h"
#include "Object.h"
#include <string.h>
#include <Function.h>
#include <GlobalVar.h>

Frame* frame_allocate(){
    Frame* temp = (Frame*)malloc(sizeof(Frame));
    memset(temp,0,sizeof(Frame));
    temp->loop_stack=list_allocate_const();
    temp->stack=list_allocate_const();
    return temp;
}


Frame* frame_build(Object* obj, List* args,int status){
    if(obj->type==&CodeType) {
        Frame* temp = frame_allocate();
        Code* codeobject = (Code*) obj;
        temp->pc = 0;
        temp->code = codeobject->byteCode;
        temp->locals = dict_allocate_const();
        temp->globals = temp->locals;
        temp->names = codeobject->names;
        temp->varNames = codeobject->varNames;
        temp->consts = codeobject->consts;
        temp->fastLocals = list_allocate_const();
        temp->status=status;
        return temp;
    }
    else if(obj->type==&FunctionType){
        Frame* temp = frame_allocate();
        Function* func = (Function*)obj;
        temp->pc=0;
        temp->code=func->codeObject->byteCode;
        temp->locals=dict_allocate_const();
        temp->fastLocals=list_allocate_const();
        temp->globals=func->global;
        temp->names=func->codeObject->names;
        temp->varNames=func->codeObject->varNames;
        temp->consts=func->codeObject->consts;
        temp->status=status;
        for (int i = 0; i < (func->argCount - func->defaultArgCount); i++)
            list_push(temp->fastLocals, list_pop(args));
        for (int i = 0; i < func->defaultArgCount; i++)
            list_push(temp->fastLocals, list_pop(func->defaultArgs));
        return temp;
    }
    else {
        Method* method = (Method*)obj;
        list_push(args,method->owner);
        return frame_build(method->func,args,status);
    }
}


void frame_destroy(Frame* self) {
    list_destroy(self->stack);
    list_destroy(self->loop_stack);
    dict_destroy(self->locals);
    list_destroy(self->fastLocals);
    free(self);
}

void frame_destroy_withoutDict(Frame* self){
    list_destroy(self->fastLocals);
    list_destroy(self->stack);
    list_destroy(self->loop_stack);
}



